#coding:utf-8
from string import *
import socket
import os
import time
import sys
from urllib import *
from urllib import toBytes
from urllib import ContentTooShortError
from urlparse import urljoin as basejoin

_urlopener = None
def Myurlretrieve(url,filename=None, reporthook=None, data=None):
  global _urlopener
  if not _urlopener:
    _urlopener = My_ReURLopener()
  return _urlopener.retrieve(url,filename, reporthook, data)

class My_ReURLopener(FancyURLopener):
  def __init__(self,proxies=None,**x509):
    FancyURLopener.__init__(self,proxies=None,**x509)
  def retrieve(self, url,filename=None, reporthook=None, data=None):
    url = unwrap(toBytes(url))
    if self.tempcache and url in self.tempcache:
      return self.tempcache[url]
    type, url1 = splittype(url)
    if filename is None and (not type or type == 'file'):
      try:
        fp = open_local_file(url1)
        hdrs = fp.info()
        fp.close()
        return url2pathname(splithost(url1)[1]), hdrs
      except IOError:
        pass
    fp = self.open(url, data)
    try:
      headers = fp.info()
      if filename:
        tfp = open(filename, 'wb')
      else:
        import tempfile
        garbage, path = splittype(url)
        garbage, path = splithost(path or "")
        path, garbage = splitquery(path or "")
        path, garbage = splitattr(path or "")
        suffix = os.path.splitext(path)[1]
        (fd, filename) = tempfile.mkstemp(suffix)
        self.__tempfiles.append(filename)
        tfp = os.fdopen(fd, 'wb')
      try:
        result = filename, headers
        if self.tempcache is not None:
          self.tempcache[url] = result
        bs = 1024*8
        size = -1
        read = 0
        blocknum = 0
        if reporthook:
          if "content-length" in headers:
            size = int(headers["Content-Length"])
          reporthook(blocknum, bs, size)
        while 1:
          time.sleep(0.001)
          block = fp.read(bs)
          if block == "":
            break
          read += len(block)
          tfp.write(block)
          blocknum += 1
          if reporthook:
            reporthook(blocknum, bs, size)
      finally:
        tfp.close()
    finally:
      fp.close()

        # raise exception if actual size does not match content-length header
    if size >= 0 and read < size:
      raise ContentTooShortError("retrieval incomplete: got only %i out "
                                       "of %i bytes" % (read, size), result)
    return result


    
